package  
{
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.ColorMaterial;
	
	import com.transmote.flar.camera.FLARCamera_PV3D;
	import com.transmote.flar.FLARManager;
	import com.transmote.flar.marker.FLARMarker;
	import com.transmote.flar.marker.FLARMarkerEvent;
	import com.transmote.flar.tracker.FLARToolkitManager;
	import flash.display.Sprite;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Rectangle;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.LazyRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	
	import flash.events.Event;
	
	import com.transmote.flar.utils.geom.PVGeomUtils;
	/**
	 * ...
	 * @author ...
	 */
	public class AnimatedARScene extends Sprite 
	{
		private const HOLE_HIGHT:int = 80
		private const HOLE_WIDTH:int = 80
		private const HOLE_DEPTH:int = 150;
		
		private var flarManager:FLARManager;
		private var marker:FLARMarker;
		private var scene:Scene3D;
		private var viewport:Viewport3D;
		private var camera:Camera3D;
		private var renderEngine:LazyRenderEngine;
		
		private var mainLight:PointLight3D;
		private var modelContainer:DisplayObject3D;
		
		private var hole:Cube;
		private var green:Cube;
		private var plane:Plane;
	
		public function AnimatedARScene() 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);		
		}	
		
		private function onAddedToStage( e:Event ): void {
			this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			
			this.flarManager = new FLARManager("../resources/flar/flarConfig.xml", new FLARToolkitManager(), this.stage);
			this.addChild(Sprite(this.flarManager.flarSource));
			this.flarManager.addEventListener(FLARMarkerEvent.MARKER_ADDED, this.onMarkerAdded);
			this.flarManager.addEventListener(FLARMarkerEvent.MARKER_UPDATED, this.onMarkerUpdated);
			this.flarManager.addEventListener(FLARMarkerEvent.MARKER_REMOVED, this.onMarkerRemoved);
			this.flarManager.addEventListener(Event.INIT, this.init3D);
		}		
		
		private function init3D( e:Event ):void {
			this.flarManager.removeEventListener(Event.INIT, this.init3D);	
			
			this.scene = new Scene3D();
			this.viewport = new Viewport3D(this.stage.stageWidth, this.stage.stageHeight);
			this.addChild(this.viewport);
			
			this.camera = new FLARCamera_PV3D(this.flarManager, new Rectangle(0, 0, this.stage.stageWidth, this.stage.stageHeight));
			this.renderEngine = new LazyRenderEngine(this.scene, this.camera, this.viewport);
			
			this.mainLight = new PointLight3D();
			this.mainLight.x = 1000;
			this.mainLight.y = 1000;
			this.mainLight.z = -1000;
			this.scene.addChild(this.mainLight);
			
			hole = new Cube( new MaterialsList({all: new FlatShadeMaterial(this.mainLight, 0x000000, 0x071016)}), HOLE_HIGHT, HOLE_WIDTH ,  HOLE_DEPTH, 5, 5, 5, Cube.ALL, Cube.TOP);
			green = new Cube(new MaterialsList( { all: new ColorMaterial(0xff0000) } ), HOLE_HIGHT, HOLE_WIDTH, HOLE_DEPTH , 5, 5, 5, 0, Cube.TOP);
			hole.rotationX =  90;
			green.rotationX =  90;
			hole.z = green.z = -0.5 * HOLE_DEPTH;
			
			this.modelContainer = new DisplayObject3D();
		
			this.modelContainer.addChild(hole);
			this.modelContainer.addChild(green);
			
			this.modelContainer.visible = false;
			this.scene.addChild(this.modelContainer);
			this.viewport.filters = [
				new ColorMatrixFilter([
					1, 0, 0, 0, 0,
					0, 1, 0, 0, 0,
					0, 0, 1, 0, 0,
					-1, 1, 1, 1, 0
				])
			];			
			
			this.addEventListener(Event.ENTER_FRAME, this.loop);
		}	
		
		private function loop( e:Event ):void {
			if (this.marker) { 
				this.modelContainer.transform = PVGeomUtils.convertMatrixToPVMatrix(this.marker.transformMatrix);
			}
			// update the Papervision3D view.
			this.renderEngine.render();
		}
		
		private function onMarkerAdded( e:FLARMarkerEvent ):void {
			trace("[" + e.marker.patternId + "] added");
			this.marker = e.marker;
			this.modelContainer.visible = true;
		}
		
		private function onMarkerRemoved( e:FLARMarkerEvent ):void {
			trace("[" + e.marker.patternId + "] removed");
			this.marker = null;
		}
		
		private function onMarkerUpdated( e:FLARMarkerEvent ):void {
			this.marker = e.marker;
			this.modelContainer.transform = PVGeomUtils.convertMatrixToPVMatrix(this.marker.transformMatrix);
		}
		
	}

}